An API-key restricted to the endpoint-scope
rbac.subjects:sync may only use
GET /api/rbac/subjects,
GET /api/rbac/subjects/{uuid}, and
PUT /api/rbac/subjects/{uuid}. Even though the global ADMIN
role is granted to its API_KEY subject, creating subjects via
POST /api/rbac/subjects is out of scope and responds with
403 Forbidden.
| name | value |
|---|---|
| subjectUuid | a91c0007-0000-0000-0000-000000000007 |
| subjectName | write.attempt.key |
An API-key can be restricted to named endpoint-scopes, here
rbac.subjects:sync, which only allows
GET /api/rbac/subjects,
GET /api/rbac/subjects/{uuid}, and
PUT /api/rbac/subjects/{uuid} (create-or-update,
incl. declarative deactivation via deactivated: true —
deliberately no DELETE). The scopes are an additional fence
on top of the roles granted to the API_KEY subject: even with the global
ADMIN role, e.g. granted to sync ALL subjects as needed for a Keycloak
subject synchronization, all endpoints outside the scopes respond with
403 Forbidden. An API-key without scopes remains
unrestricted.
The scopes property restricts the API-key to the given
named endpoint-scopes. The response contains the generated clear-text
API-key (property apiKey) exactly once; it cannot be
retrieved again.
HTTP POST "/api/rbac/subjects" \
-H "Authorization: Bearer $HSADMINNG_JWT_BEARER" \
`# {` \
`# "sub" : "uuid<hsh-alex_superuser>"` \
`# }` \
<<EOF
{
"uuid" : "a91c0007-0000-0000-0000-000000000007",
"name" : "write.attempt.key",
"type" : "API_KEY",
"scopes" : [ "rbac.subjects:sync" ]
}
EOF
=> status: 201 CREATED a91c0007-0000-0000-0000-000000000007
{
"uuid" : "a91c0007-0000-0000-0000-000000000007",
"name" : "write.attempt.key",
"organization" : "write",
"type" : "API_KEY",
"apiKey" : "hsak_write.attempt.key.c35de7efee41f9207cfc8a5bd3308bdefeaee70707ee18b36d7311c16cbcb00c",
"scopes" : [ "rbac.subjects:sync" ],
"expiresAt" : null
}
The grant API needs the UUID of the role which we want to grant.
HTTP GET "/api/rbac/roles?name=rbac.global%23global%3AADMIN" \
-H "Authorization: Bearer $HSADMINNG_JWT_BEARER" \
`# {` \
`# "sub" : "uuid<hsh-alex_superuser>"` \
`# }`
=> status: 200 OK
[ {
"uuid" : "589a6260-757d-4e3e-a2b7-08ca8b758868", // globalAdminRoleUuidToGrant
"object.uuid" : "9b7b3d20-a88f-4c19-8bc7-efdb8dd24832",
"objectTable" : "rbac.global",
"objectIdName" : "global",
"roleType" : "ADMIN",
"roleName" : "rbac.global#9b7b3d20-a88f-4c19-8bc7-efdb8dd24832:ADMIN",
"roleIdName" : "rbac.global#global:ADMIN"
} ]
HTTP POST "/api/rbac/grants" \
-H "Authorization: Bearer $HSADMINNG_JWT_BEARER" \
`# {` \
`# "sub" : "uuid<hsh-alex_superuser>"` \
`# }` \
-H 'Hostsharing-Assumed-Roles: rbac.global#global:ADMIN' \
<<EOF
{
"assumed" : true,
"grantedRole.uuid" : "589a6260-757d-4e3e-a2b7-08ca8b758868", // globalAdminRoleUuidToGrant
"granteeSubject.uuid" : "a91c0007-0000-0000-0000-000000000007"
}
EOF
=> status: 201 CREATED 589a6260-757d-4e3e-a2b7-08ca8b758868 // globalAdminRoleUuidToGrant
HTTP GET "/api/rbac/subjects" \
-H "Hostsharing-Api-Key: $HSADMINNG_API_KEY"
=> status: 200 OK
[
{
"uuid" : "242a0005-0000-0000-0000-000000000005",
"name" : "abc-peter.smith",
"organization" : "abc",
"type" : "USER"
},
{
"uuid" : "ba2da4ec-1b23-4ecb-9f83-c4c75f187aea",
"name" : "/abc-Team",
"organization" : "abc",
"type" : "GROUP"
},
{
"uuid" : "a91c0005-0000-0000-0000-000000000005", // ApiKey-Subject: bootstrapped.key
"name" : "bootstrapped.key",
"organization" : "bootstrapped",
"type" : "API_KEY"
},
{
"uuid" : "242a0006-0000-0000-0000-000000000006",
"name" : "def-peter.smith",
"organization" : "def",
"type" : "USER"
},
{
"uuid" : "ba600783-cdd0-4616-9bf6-9d876ad5d40b",
"name" : "/def-Team",
"organization" : "def",
"type" : "GROUP"
},
"..."
]
HTTP GET "/api/rbac/subjects/a91c0007-0000-0000-0000-000000000007" \
-H "Hostsharing-Api-Key: $HSADMINNG_API_KEY"
=> status: 200 OK
{
"uuid" : "a91c0007-0000-0000-0000-000000000007",
"name" : "write.attempt.key",
"organization" : "write",
"type" : "API_KEY"
}
HTTP POST "/api/rbac/subjects" \
-H "Hostsharing-Api-Key: $HSADMINNG_API_KEY" \
<<EOF
{
"name" : "never.created.key",
"type" : "API_KEY"
}
EOF
=> status: 403 FORBIDDEN
{
"path" : "/api/rbac/subjects",
"statusCode" : 403,
"statusPhrase" : "Forbidden",
"message" : "ERROR: [403] API-key scopes do not allow POST /api/rbac/subjects"
}
generated on 2026-08-10 03:08:47 for branch HEAD